package {
	import ypmits.bitmap.vo.ParticleDataVO;
	import ypmits.components.ComponentSkin;
	import ypmits.components.buttons.CloseButton;
	import ypmits.components.slider.Slider;
	import ypmits.components.slider.event.SliderEvent;
	import ypmits.setup.EasySetup;
	import ypmits.setup.EasySetupInput;
	import ypmits.setup.view.FullScreenButtonGraphic;

	import com.greensock.TweenLite;
	import com.greensock.easing.Back;
	import com.greensock.easing.Cubic;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BitmapFilter;
	import flash.filters.ConvolutionFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Sound;
	import flash.net.URLRequest;

	/**
	 * @author Dave Lenz
	 */
	public class BitmapParticle extends Sprite {

		private var particledata : Array;
		private var picture : Sprite;
		private var _totalFadedIn : int;
		private var closebutton : CloseButton;
		private var matrixX : Number = 3;
		private var matrixY : Number = 3;
		private var divisor : Number = 9;
		private var outlinematrix : Array;
		private var sharpnessmatrix : Array;
		private var brightnessmatrix : Array;

		
		public function BitmapParticle() {
			var _i : EasySetupInput = new EasySetupInput( );
			_i.fullscreenbuttongraphic = new FullScreenButtonGraphic( 15, 15, 0xFFFFFF, stage );
			
			EasySetup.instance.init( this, _i );
			EasySetup.instance.debug = true;
			draw( );
		}

		
		private function draw() : void {
			picture = new Sprite( );
			picture.x = 70;
			picture.y = 0;
			addChild( picture );
			
			var skin : ComponentSkin = new ComponentSkin( );
			skin.name = "outline";
			skin.width = 400;
			skin.backgroundalpha = .5;
			skin.func = applyOutline;
			skin.minimumvalue = 0;
			skin.maximumvalue = 30;
			skin.defaultvalue = 0;
			
			var outlineslider : Slider = new Slider( skin );
			outlineslider.x = 80;
			outlineslider.y = 10;
			addChild( outlineslider );
			
			skin.name = "brightness";
			skin.func = applyBrightness;
			skin.minimumvalue = 0;
			skin.maximumvalue = 10;
			skin.defaultvalue = 0;
			
			var brightnessslider : Slider = new Slider( skin );
			brightnessslider.x = 80;
			brightnessslider.y = 40;
			addChild( brightnessslider );
			
			skin.name = "sharpness";
			skin.func = applySharpness;
			skin.minimumvalue = 0;
			skin.maximumvalue = 20;
			skin.defaultvalue = 0;
			
			var sharpnessslider : Slider = new Slider( skin );
			sharpnessslider.x = 80;
			sharpnessslider.y = 70;
			addChild( sharpnessslider );
			
			closebutton = new CloseButton();
			closebutton.x = 500;
			closebutton.y = 10;
			closebutton.addEventListener( MouseEvent.CLICK, fadeOut );
			addChild( closebutton );
			
			loadPicture( "stuff/george.png" );
			loadSound( "stuff/rave.mp3" );
		}

		
		private function loadSound( url : String ) : void {
			var s : Sound = new Sound( );
			//s.addEventListener( ProgressEvent.PROGRESS, progHandler );
			s.load( new URLRequest( url ) );
			s.play( );
		}

		
		private function loadPicture( url : String ) : void {
			var l : Loader = new Loader( );
			l.contentLoaderInfo.addEventListener( Event.COMPLETE, completeHandler );
			l.load( new URLRequest( url ) );
		}

		
		private function completeHandler( e : Event ) : void {
			_totalFadedIn = 0;
			
			var bitmap : Bitmap = Bitmap( LoaderInfo( e.currentTarget ).content );
			bitmap.smoothing = true;
			
			particledata = makeBitmapParticles( bitmap.bitmapData, 10, 10, true );

			var totaltime : Number = 1;
			var t : Number = totaltime / particledata.length;
			for (var i : int = 0; i < particledata.length; i++) {

				var p : ParticleDataVO = ParticleDataVO( particledata[i] );
				picture.addChild( p.obj );
				p.obj.x = p.x;
				p.obj.y = EasySetup.instance.stage.stageHeight;
					
				TweenLite.to( p.obj, Math.random( ) * 1, {x:p.x, y:p.y, delay:t * i, ease:Back.easeOut, onComplete:doneFadeIn} );
			}
		}

		
		private function doneFadeIn() : void {
			_totalFadedIn++;
			if( particledata.length == _totalFadedIn ) {
			}
		}

		
		private function fadeOut(event : MouseEvent) : void {
			closebutton.removeEventListener( MouseEvent.CLICK, fadeOut );
			
			particledata.reverse( );
			for (var i : int = 0; i < particledata.length; i++) {

				var p : ParticleDataVO = ParticleDataVO( particledata[i] );
					
				TweenLite.to( p.obj, Math.random( ) * 1.5, {x:p.x, y:EasySetup.instance.stage.stageHeight, delay:(2 / particledata.length) * i, ease:Cubic.easeIn, onComplete:doneFadeOut} );
			}
		}

		
		private function doneFadeOut() : void {
		}

		
		private function applyBrightness( e : SliderEvent ) : void {
			trace( "BitmapParticle.applyBrightness("+[e]+")" );
			brightnessmatrix = [ e.value, e.value, e.value,
                                e.value, 0, e.value,
                                e.value, e.value, e.value ];
			var filterbrightness : BitmapFilter = new ConvolutionFilter( matrixX, matrixY, brightnessmatrix, divisor );
			picture.filters = [filterbrightness];
		}

		
		private function applySharpness( e : SliderEvent ) : void {
			trace( "BitmapParticle.applySharpness("+[e]+")" );
			sharpnessmatrix = [ 0, -(e.value / e.value ), 0,
                               -(e.value / e.value ), e.value, -(e.value / e.value ),
                                0, -(e.value / e.value ), 0 ];
			var filtersharpness : BitmapFilter = new ConvolutionFilter( matrixX, matrixY, sharpnessmatrix, divisor );
			picture.filters = [filtersharpness];
		}

		
		private function applyOutline( e : SliderEvent ) : void {
			trace( "BitmapParticle.applyOutline("+[e]+")" );
			outlinematrix = [ -e.value, e.value, 0,
                                -e.value, e.value, 0,
                                -e.value, e.value, 0 ];
			var filteroutline : BitmapFilter = new ConvolutionFilter( matrixX, matrixY, outlinematrix, divisor );
			picture.filters = [filteroutline];
		}

		
		private function makeBitmapParticles( bitmapdata : BitmapData, width : Number, height : Number, alpha : Boolean = false ) : Array {
			var particles : Array = [];
			
			var columns : Number = Math.ceil( bitmapdata.width / width );
			var rows : Number = Math.ceil( bitmapdata.height / height );
			
			var i : int;
			var bmd : BitmapData;
			var pdata : ParticleDataVO;
			for ( i = 0; i < rows; i++) {
				for (var j : int = 0; j < columns; j++) {
					pdata = new ParticleDataVO( );
					bmd = new BitmapData( width, height, alpha, Math.random( ) * 0xFF9900 );
					bmd.copyPixels( bitmapdata, new Rectangle( j * width, i * height, width, height ), new Point( 0, 0 ) );

					pdata.x = j * width;
					pdata.y = i * height;
					pdata.obj = new Bitmap( bmd );

					particles.push( pdata );
				}
			}
			return particles;
		}
	}
}
